package sdk.org.apache.shiro.G2_使用.C06_授权;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.permission.WildcardPermission;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;

import com.titan.core.utils.data.SetUtils;
import com.titan.core.utils.debug.Timer;
import com.titan.core.utils.io.ConsoleUtils;

import sdk.org.apache.shiro.utils.ShiroUtils;

public class 验证权限 {
    public static void main(String[] args) {
        Timer timer = Timer.$();
        try {
            run(timer);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            timer.print("执行总用时");
            System.exit(0);
        }
    }

    
    private static void run(Timer timer) throws Exception {
        ShiroUtils.init(
              new AuthorizingRealm() {
                protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
                    //null usernames are invalid
                    if (principals == null) {
                        throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
                    }
                    String username = (String) getAvailablePrincipal(principals);
//                    ConsoleUtils.log("doGetAuthorizationInfo...", "username", username);
                    
                    Set<String> roles = new HashSet<String>();
                    Set<String> permissions = new HashSet<String>();
                    
                    if("zhang".equals(username)) {
                        SetUtils.toSet(roles, "role1", "role2");
                        // role1: 对资源user拥有create、update权限
                        SetUtils.toSet(permissions, "user:create", "user:update");
                        // role2: 对资源user拥有create、delete权限
                        SetUtils.toSet(permissions, "user:create", "user:delete");
                        // role3: 对资源user拥有create权限
                        SetUtils.toSet(permissions, "system:user:create");
                    } else if("wang".equals(username)) {
                        SetUtils.toSet(roles, "role1");
                        // role1: 对资源user拥有create、update权限
                        SetUtils.toSet(permissions, "user:create", "user:update");
                    } else if("li".equals(username)) {
                        SetUtils.toSet(roles, "role41", "role42"
                                            , "role51", "role52", "role53"
                                            , "role61", "role62"
                                            , "role71", "role72", "role73", "role74", "role75"
                                            , "role81", "role82");
                        SetUtils.toSet(permissions, "system:user:update", "system:user:delete");
                        SetUtils.toSet(permissions, "system:user:update", "delete");
                        SetUtils.toSet(permissions, "system:user:create", "update", "delete", "view");
                        SetUtils.toSet(permissions, "system:user:*");  // 对资源system:user拥有所有权限
                        SetUtils.toSet(permissions, "system:user");  // 对资源system:user拥有所有权限
                        SetUtils.toSet(permissions, "*:view");        // 对资源拥有所有权限（如匹配user:view）
                        SetUtils.toSet(permissions, "*:*:view");   // 对资源拥有所有权限（如匹配system:user:view，即和之上的不等价）
                        SetUtils.toSet(permissions, "user:view:1");    // 对资源user的1实例拥有view权限
                        SetUtils.toSet(permissions, "user:update,delete:1");    // 对资源user的1实例拥有update、delete权限
                        SetUtils.toSet(permissions, "user:*:1");    // 对资源user的1实例拥有所有权限
                        SetUtils.toSet(permissions, "user:auth:*"); // 对资源user的所有实例拥有auth权限
                        SetUtils.toSet(permissions, "user:*:*");    // 对资源user的所有实例拥有所有权限
                        SetUtils.toSet(permissions, "menu:*");      // 等价于menu:*:*
                        SetUtils.toSet(permissions, "organization");
                    }
                    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(roles);
                    authorizationInfo.setStringPermissions(permissions);
                    return authorizationInfo;
                }
                protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
                    String username = (String)token.getPrincipal();  //得到用户名
                    String password = new String((char[])token.getCredentials()); //得到密码
                    ConsoleUtils.log("doGetAuthenticationInfo", "username", username, "password", password);
                    if("zhang".equals(username) && "123".equals(password)) {
                        return new SimpleAuthenticationInfo(username, password, getName());
                    }
                    if("li".equals(username) && "123".equals(password)) {
                        return new SimpleAuthenticationInfo(username, password, getName());
                    }
                    throw new UnknownAccountException();
                }
              });
        
        
        Subject currentUser = ShiroUtils.login("zhang", "123", true);
        try {
            ConsoleUtils.log("是否有权限user:create", currentUser.isPermitted("user:create"));
            ConsoleUtils.log("是否有权限user:view", currentUser.isPermitted("user:view"));
            ConsoleUtils.log("是否有权限user:update和user:delete", currentUser.isPermittedAll("user:update", "user:delete"));
            
            //断言拥有权限：user:create
            currentUser.checkPermission("user:create");
            //断言拥有权限：user:delete and user:update
            currentUser.checkPermissions("user:delete", "user:update");
            try {
                //断言拥有权限：user:view 失败抛出异常
                currentUser.checkPermissions("user:view");        
            } catch (UnauthorizedException e) {
                System.err.println(e.toString());
            }
        } finally {
            ShiroUtils.logout();
        }
        
        currentUser = ShiroUtils.login("li", "123", true);
        try {
            currentUser.checkPermissions("system:user:update", "system:user:delete");
            currentUser.checkPermissions("system:user:update,delete");
            currentUser.checkPermissions("system:user:create,delete,update:view");
            currentUser.checkPermissions("system:user:*");
            currentUser.checkPermissions("system:user");
            currentUser.checkPermissions("user:view");
            currentUser.checkPermissions("system:user:view");
            currentUser.checkPermissions("user:view:1");
            currentUser.checkPermissions("user:delete,update:1");
            currentUser.checkPermissions("user:update:1", "user:delete:1");
            currentUser.checkPermissions("user:update:1", "user:delete:1", "user:view:1");
            currentUser.checkPermissions("user:auth:1", "user:auth:2");
            currentUser.checkPermissions("menu:view:1");
            currentUser.checkPermissions("organization");
            currentUser.checkPermissions("organization:view");
            currentUser.checkPermissions("organization:view:1");
            currentUser.checkPermission("menu:view:1");
            currentUser.checkPermission(new WildcardPermission("menu:view:1"));
        } finally {
            ShiroUtils.logout();
        }
    }
}
